package com.uuah.server.config.spring.parsers.delegate;

import org.springframework.beans.factory.support.AbstractBeanDefinition;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;

import com.uuah.server.config.spring.parsers.IUuahDefinitionParser;
import com.uuah.server.config.spring.parsers.IUuahDefinitionParserConfiguration;
import com.uuah.server.config.spring.parsers.UuahChildDefinitionParser;

/**
 * This allows several parsers to be used on a single element, creating a parent
 * bean with the first parser and then extending that with child parsers.
 * 
 * <p>
 * Note that this make a lot of assumptions about what type of parser is used.
 */
public abstract class AbstractSingleParentFamilyDefinitionParser extends
		AbstractFirstResultSerialDefinitionParser {

	public AbstractSingleParentFamilyDefinitionParser() {
		super();
	}

	public AbstractSingleParentFamilyDefinitionParser(boolean doReset) {
		super(doReset);
	}

	protected UuahChildDefinitionParser addChildDelegate(
			UuahChildDefinitionParser delegate) {
		return (UuahChildDefinitionParser) super.addDelegate(delegate);
	}

	protected IUuahDefinitionParserConfiguration addDelegate(
			IUuahDefinitionParser delegate) {
		if (size() > 0) {
			return addDelegateAsChild(delegate);
		} else {
			return super.addDelegate(delegate);
		}
	}

	protected IUuahDefinitionParserConfiguration addDelegateAsChild(
			IUuahDefinitionParser delegate) {
		if (delegate instanceof UuahChildDefinitionParser) {
			return addChildDelegate((UuahChildDefinitionParser) delegate);
		} else {
			throw new IllegalStateException(
					"Children must implement child interface");
		}
	}

	protected AbstractBeanDefinition doSingleBean(int index,
			IUuahDefinitionParser parser, Element element,
			ParserContext parserContext) {
		if (0 != index) {
			((UuahChildDefinitionParser) parser).forceParent(firstDefinition);
			// we need this because we often block "everything but" which would
			// mean
			// being unable to set ourselves on the parent
			((UuahChildDefinitionParser) parser)
					.getTargetPropertyConfiguration().setIgnoredDefault(false);
		}
		return super.doSingleBean(index, parser, element, parserContext);
	}

}
